/*
 *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "tizensysteminfo.h"

#include "../pluginregistry.h"

#if QT_VERSION < 0x050000
#include <QSystemDeviceInfo>
#include <QSystemInfo>
#else
#include <QDeviceInfo>
#include <QtSystemInfo>
#endif

#include <qtextdocument.h>
#include <QtGlobal>
#include <QWidget>
#include <QNetworkInterface>
#include <QSystemNetworkInfo>
#include <QSystemDisplayInfo>
#include <QSystemBatteryInfo>
#include <QDebug>
#include <stdlib.h>

#define CORDOVA "1.3.0"

#ifdef QTM_NAMESPACE
QTM_USE_NAMESPACE
#endif

// Create static instance of ourself
TizenSystemInfo* TizenSystemInfo::m_tizsysinfo = new TizenSystemInfo();

/**
 * Constructor - NOTE: Never do anything except registering the plugin
 */
TizenSystemInfo::TizenSystemInfo() : CPlugin() {
    PluginRegistry::getRegistry()->registerPlugin("tizen.systeminfo", this);
}

void TizenSystemInfo::getPropertyValue(int scId, int ecId, QString property) {
    Q_UNUSED(ecId)

    if (property.toLower() == "power") {
        QSystemBatteryInfo *batteryInfo = new QSystemBatteryInfo(this);
        double level = batteryInfo->remainingCapacityPercent() / 100.0;
        QString charging = "false";
        if (batteryInfo->chargingState() == QSystemBatteryInfo::Charging) {
            charging = "true";
        }
        this->callback(scId, "{level : " + QString::number(level)
               + ", isCharging : " + charging + "}");
    } else if (property.toLower() == "cpu") {
        double loadavg;
        getloadavg(&loadavg, 1);
        loadavg /= sysconf(_SC_NPROCESSORS_ONLN);
        this->callback(scId, "{load : " + QString::number(loadavg) + "}");
    } else if (property.toLower() == "display") {
        QWidget *dw = new QWidget();
        QSystemDisplayInfo *di = new QSystemDisplayInfo();
        this->callback(scId, "{resolutionWidth : " + QString::number(dw->width())
                + ", resolutionHeight : " + QString::number(dw->height())
                + ", dotsPerInchWidth : " + QString::number(dw->physicalDpiX())
                + ", dotsPerInchHeight : " + QString::number(dw->physicalDpiY())
                + ", physicalWidth : " + QString::number(dw->widthMM())
                + ", physicalHeight : " + QString::number(dw->heightMM())
                + ", brightness : " + QString::number(di->displayBrightness(0) / 100.0) + "}");
    } else if (property.toLower() == "device") {
        QSystemDeviceInfo *sdi = new QSystemDeviceInfo();
        this->callback(scId, "{imei : \"" + sdi->imei() + "\""
                + ", model : \"" + Qt::escape(sdi->model()) + "\""
                + ", version : \"" + qVersion() + "\""
                + ", vendor : \"" + Qt::escape(sdi->manufacturer()) + "\"}");
    } else if (property.toLower() == "wifinetwork") {
        QNetworkInterface wlan = QNetworkInterface::interfaceFromName("wlan0");
        QSystemNetworkInfo *netInfo = new QSystemNetworkInfo();
        QString status = "OFF";
        QString ip = "0.0.0.0";
        QString ssid = netInfo->networkName(QSystemNetworkInfo::WlanMode);
        double signalStrength = 0;
        if (wlan.flags().testFlag(QNetworkInterface::IsUp)) {
            status = "ON";
	        if(wlan.addressEntries().count() > 0) {
                ip = wlan.addressEntries()[0].ip().toString();
            }
            signalStrength = netInfo->networkSignalStrength(QSystemNetworkInfo::WlanMode) / 100.0;
        }
        this->callback(scId, "{status : \"" + status + "\""
                + ", ssid : \"" + Qt::escape(ssid) + "\""
                + ", ipAddress : \"" + ip + "\""
                + ", signalStrength : " + QString::number(signalStrength) + " }");
    } else if (property.toLower() == "cellularnetwork") {
        QNetworkInterface phonet = QNetworkInterface::interfaceFromName("phonet0");
        QSystemNetworkInfo *netInfo = new QSystemNetworkInfo();
        QString status = "OFF";
        QString ip = "0.0.0.0";
        QString apn = netInfo->networkName(QSystemNetworkInfo::GsmMode);
        if (phonet.flags().testFlag(QNetworkInterface::IsUp)) {
            status = "ON";
            if(phonet.addressEntries().count() > 0) {
                ip = phonet.addressEntries()[0].ip().toString();
            }
        }
        int mcc = 0;
        int mnc = 0;
        int cellId = netInfo->cellId();
        int lac = netInfo->locationAreaCode();
        QString roaming = "false";
        if (netInfo->networkStatus(QSystemNetworkInfo::GsmMode) == QSystemNetworkInfo::Roaming) {
            roaming = "true";
        }
        this->callback(scId, "{status : \"" + status + "\""
                + ", apn : \"" + Qt::escape(apn) + "\""
                + ", ipAddress : \"" + ip + "\""
                + ", mcc : " + QString::number(mcc) +
                + ", mnc : " + QString::number(mnc) +
                + ", cellId : " + QString::number(cellId) +
                + ", lac : " + QString::number(lac) +
                + ", isRoaming : " + roaming + " }");

    }
}


void TizenSystemInfo::addPropertyValueChangeListener(int scId, int ecId, int listenerId, QString property, QList<QString> options) {
    printf("Setting up property listener %d for %s\n", listenerId, property);
    if (property.toLower() == "power") {
        QSystemBatteryInfo *batteryInfo = new QSystemBatteryInfo(this); 
        TizenSystemInfoListener *listener = new TizenSystemInfoListener();
        listener->id = listenerId;
        listener->scId = scId;
        listener->ecId = ecId;
        listener->tizenSystemInfo = this;
        QObject::connect(batteryInfo, SIGNAL(QSystemBatteryInfo::remainingCapacityPercentChanged), listener, SLOT(batteryResponse));
        QObject::connect(batteryInfo, SIGNAL(QSystemBatteryInfo::chargingStateChanged), listener, SLOT(batteryResponse));
    }
}


TizenSystemInfoListener::TizenSystemInfoListener() {

}


void TizenSystemInfoListener::batteryResponse(int ignored) {
    Q_UNUSED(ignored)

    QSystemBatteryInfo *batteryInfo = new QSystemBatteryInfo(this);
    double level = batteryInfo->remainingCapacityPercent() / 100.0;
    QString charging = "false";
    if (batteryInfo->chargingState() == QSystemBatteryInfo::Charging) {
        charging = "true";
    }
    printf("Sending battery update\n");
    tizenSystemInfo->callback(scId, "{level : " + QString::number(level)
           + ", isCharging : " + charging + "}");
}
